home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / mesh_obj.pro < prev    next >
Text File  |  1997-07-08  |  29KB  |  732 lines

  1. ; $Id: mesh_obj.pro,v 1.3 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1994-1997, Research Systems, Inc.  All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;       MESH_OBJ
  8. ;
  9. ; PURPOSE:
  10. ;       MESH_OBJ generates a polygon mesh (vertex list and polygon list) that
  11. ;       represent the desired primitive object. The available primitive
  12. ;       objects are: triangulated surface, rectangular surface, polar surface,
  13. ;       cylindrical surface, spherical surface, surface of extrusion, surface
  14. ;       of revolution, and ruled surface.
  15. ;
  16. ; CATEGORY:
  17. ;       Graphics.
  18. ;
  19. ; CALLING SEQUENCE:
  20. ;       MESH_OBJ, Type, Vertex_List, Polygon_List, Array1, Array2
  21. ;
  22. ; INPUTS:
  23. ;
  24. ;       Type:   An integer which specifies what type of object to create.
  25. ;
  26. ;                  TYPE CODE:      SURFACE TYPE:
  27. ;                  ----------      -------------
  28. ;
  29. ;                  0               TRIANGULATED
  30. ;                  1               RECTANGULAR
  31. ;                  2               POLAR
  32. ;                  3               CYLINDRICAL
  33. ;                  4               SPHERICAL
  34. ;                  5               EXTRUSION
  35. ;                  6               REVOLUTION
  36. ;                  7               RULED
  37. ;
  38. ;                  ELSE            none
  39. ;
  40. ;       Vertex_List:
  41. ;               On input, Vertex_List may be undefined. On output, it contains
  42. ;               the mesh vertices. Vertex_List and Polygon_List have the same
  43. ;               format as the lists returned by the SHADE_VOLUME procedure.
  44. ;
  45. ;       Polygon_List:
  46. ;               On input, Polygon_List may be undefined. On output, it contains
  47. ;               the mesh indexes.
  48. ;
  49. ;       Array1:
  50. ;               An array whose use depends on the type of object being created.
  51. ;
  52. ;                  SURFACE TYPE:   Array1 type
  53. ;                  -------------   --------------------------------------------
  54. ;
  55. ;                  TRIANGULATED    A (3, n) array containing random [x, y, z]
  56. ;                                  points to build a triangulated surface from.
  57. ;                                  The resulting polygon mesh will have n
  58. ;                                  vertices. When shading a triangulated mesh,
  59. ;                                  the shading array should have (n) elements.
  60. ;
  61. ;                  RECTANGULAR     A two dimensional (n, m) array containing
  62. ;                                  z values. The resulting polygon mesh will
  63. ;                                  have n*m vertices.
  64. ;                                  When shading a rectangular mesh, the shading
  65. ;                                  array should have (n, m) elements.
  66. ;
  67. ;                  POLAR           A two dimensional (n, m) array containing
  68. ;                                  z values. The resulting polygon mesh will
  69. ;                                  have n*m vertices. The n dimension of the
  70. ;                                  array is mapped to the polar angle, and the
  71. ;                                  m dimension is mapped to the polar radius.
  72. ;                                  When shading a polar mesh, the shading array
  73. ;                                  should have (n, m) elements.
  74. ;
  75. ;                  CYLINDRICAL     A two dimensional (n, m) array containing
  76. ;                                  radius values. The resulting polygon mesh
  77. ;                                  will have n*m vertices. The n dimension of
  78. ;                                  the array is mapped to the polar angle,
  79. ;                                  and the m dimension is mapped to the Z axis.
  80. ;                                  When shading a cylindrical mesh, the shading
  81. ;                                  array should have (n, m) elements.
  82. ;
  83. ;                  SPHERICAL       A two dimensional (n, m) array containing
  84. ;                                  radius values. The resulting polygon mesh
  85. ;                                  will have n*m vertices. The n dimension of
  86. ;                                  the array is mapped to the longitude (0.0 to
  87. ;                                  360.0 degrees), and the m dimension is
  88. ;                                  mapped to the latitude (-90.0 to +90.0
  89. ;                                  degrees).
  90. ;                                  When shading a spherical mesh, the shading
  91. ;                                  array should have (n, m) elements.
  92. ;
  93. ;                  EXTRUSION       A (3, n) array of connected 3-D points which
  94. ;                                  define the shape to extrude. The resulting
  95. ;                                  polygon mesh will have n*(steps+1) vertices
  96. ;                                  (where steps is the number of "segments" in
  97. ;                                  the extrusion). (See the P1 keyword).
  98. ;                                  If the order of the elements in Array1 is
  99. ;                                  reversed, then the polygon facing is
  100. ;                                  reversed.
  101. ;                                  When shading an extrusion mesh, the shading
  102. ;                                  array should have (n, steps+1) elements.
  103. ;
  104. ;                  REVOLUTION      A (3, n) array of connected 3-D points which
  105. ;                                  define the shape to revolve. The resulting
  106. ;                                  polygon mesh will have n*((steps>3)+1)
  107. ;                                  vertices (where steps is the number of
  108. ;                                  "steps" in the revolution). (See the P1
  109. ;                                  keyword). If the order of the elements in
  110. ;                                  Array1 is reversed, then the polygon facing
  111. ;                                  is reversed.
  112. ;                                  When shading a revolution mesh, the shading
  113. ;                                  array should have (n, (steps>3)+1) elements.
  114. ;
  115. ;                  RULED           A (3, n) array of connected 3-D points which
  116. ;                                  define the shape of the first ruled vector.
  117. ;                                  The optional (3, m) Array2 parameter defines
  118. ;                                  the shape of the second ruled vector. The
  119. ;                                  resulting polygon mesh will have
  120. ;                                  (n>m)*(steps+1) vertices (where steps is the
  121. ;                                  number of intermediate "steps"). (See the P1
  122. ;                                  keyword).
  123. ;                                  When shading a ruled mesh, the shading
  124. ;                                  array should have (n>m, steps+1) elements.
  125. ;
  126. ; OPTIONAL INPUTS:
  127. ;
  128. ;       Array2:
  129. ;               If the object type is 7 (Ruled Surface) then Array2 is a (3, m)
  130. ;               array containing the 3-D points which define the second ruled
  131. ;               vector. If Array2 has fewer elements than Array1 then Array2 is
  132. ;               processed with CONGRID to give it the same number of elements
  133. ;               as Array1. If Array1 has fewer elements than Array2 then Array1
  134. ;               is processed with CONGRID to give it the same number of
  135. ;               elements as Array2.
  136. ;               Array2 MUST be supplied if the object type is 7. Otherwise,
  137. ;               Array2 is ignored.
  138. ;
  139. ; KEYWORD PARAMETERS:
  140. ;
  141. ;       P1 - P5:
  142. ;               The meaning of the keywords P1 through P5 vary depending upon
  143. ;               the object type.
  144. ;
  145. ;                  SURFACE TYPE:   Keywords
  146. ;                  -------------   --------------------------------------------
  147. ;
  148. ;                  TRIANGULATED    P1, P2, P3, P4, and P5 are ignored.
  149. ;
  150. ;                  RECTANGULAR     If Array1 is an (n, m) array, and if P1 has
  151. ;                                  n elements, then the values contained in
  152. ;                                  P1 are the X coordinates for each column of
  153. ;                                  vertices. Otherwise, FINDGEN(n) is used for
  154. ;                                  the X coordinates. If P2 has m elements,
  155. ;                                  then the values contained in P2 are the Y
  156. ;                                  coordinates for each row of vertices.
  157. ;                                  Otherwise, FINDGEN(m) is used for the Y
  158. ;                                  coordinates. The polygon facing is reversed
  159. ;                                  if the order of either P1 or P2 (but not
  160. ;                                  both) is reversed.
  161. ;                                  P3, P4, and P5 are ignored.
  162. ;
  163. ;                  POLAR           P1 specifies the polar angle of the first
  164. ;                                  column of Array1 (the default is 0). P2
  165. ;                                  specifies the polar angle of the last column
  166. ;                                  of Array1 (the default is 2*PI). If P2 is
  167. ;                                  less than P1 then the polygon facing is
  168. ;                                  reversed. P3 specifies the radius of the
  169. ;                                  first row of Array1 (the default is 0). P4
  170. ;                                  specifies the radius of the last row of
  171. ;                                  Array1 (the default is m-1). If P4 is less
  172. ;                                  than P3 then the polygon facing is reversed.
  173. ;                                  P5 is ignored.
  174. ;
  175. ;                  CYLINDRICAL     P1 specifies the polar angle of the first
  176. ;                                  column of Array1 (the default is 0). P2
  177. ;                                  specifies the polar angle of the last column
  178. ;                                  of Array1 (the default is 2*PI). If P2 is
  179. ;                                  less than P1 then the polygon facing is
  180. ;                                  reversed. P3 specifies the Z coordinate of
  181. ;                                  the first row of Array1 (the default is 0).
  182. ;                                  P4 specifies the Z coordinate of the last
  183. ;                                  row of Array1 (the default is m-1). If P4 is
  184. ;                                  less than P3 then the polygon facing is
  185. ;                                  reversed. P5 is ignored.
  186. ;
  187. ;                  SPHERICAL       P1 specifies the longitude of the first
  188. ;                                  column of Array1 (the default is 0). P2
  189. ;                                  specifies the longitude of the last column
  190. ;                                  of Array1 (the default is 2*PI). IF P2 is
  191. ;                                  less than P1 then the polygon facing is
  192. ;                                  reversed. P3 specifies the latitude of the
  193. ;                                  first row of Array1 (the default is -PI/2).
  194. ;                                  P4 specifies the latitude of the last row of
  195. ;                                  Array1 (the default is +PI/2). If P4 is less
  196. ;                                  than P3 then the polygon facing is reversed.
  197. ;                                  P5 is ignored.
  198. ;
  199. ;                  EXTRUSION       P1 specifies the number of steps in the
  200. ;                                  extrusion (the default is 1). P2 is a three
  201. ;                                  element vector specifying the direction
  202. ;                                  (and length) of the extrusion (the default
  203. ;                                  is [0, 0, 1]). P3, P4, and P5 are ignored.
  204. ;
  205. ;                  REVOLUTION      P1 specifies the number of "facets" in the
  206. ;                                  revolution (the default is 3). If P1 is less
  207. ;                                  than 3 then 3 is used. P2 is a three element
  208. ;                                  vector specifying a point that the rotation
  209. ;                                  vector passes through (the default is
  210. ;                                  [0, 0, 0]). P3 is a three element vector
  211. ;                                  specifying the direction of the rotation
  212. ;                                  vector (the default is [0, 0, 1]). P4
  213. ;                                  specifies the starting angle for the
  214. ;                                  revolution (the default is 0). P5 specifies
  215. ;                                  the ending angle for the revolution (the
  216. ;                                  default is 2*PI). If P5 is less than P4 then
  217. ;                                  the polygon facing is reversed.
  218. ;
  219. ;                  RULED           P1 specifies the number of "steps" in the
  220. ;                                  ruling (the default is 1).
  221. ;                                  P2, P3, P4, and P5 are ignored.
  222. ;
  223. ;       DEGREES:   If set, then the input parameters are in degrees
  224. ;                  (where applicable). Otherwise, the angles are in
  225. ;                  radians.
  226. ;
  227. ; EXAMPLE:
  228. ;
  229. ;       ; Create a 48x64 cylinder with a constant radius of 0.25.
  230. ;       MESH_OBJ, 3, Vertex_List, Polygon_List, Replicate(0.25, 48, 64), $
  231. ;          P4=0.5
  232. ;
  233. ;       ; Transform the vertices.
  234. ;       T3d, /Reset
  235. ;       T3d, Rotate=[0.0, 30.0, 0.0]
  236. ;       T3d, Rotate=[0.0, 0.0, 40.0]
  237. ;       T3d, Translate=[0.25, 0.25, 0.25]
  238. ;       Vertex_List = Vert_T3d(Vertex_List)
  239. ;
  240. ;       ; Create the window and view.
  241. ;       Window, 0, Xsize=512, Ysize=512
  242. ;       Create_View, Winx=512, Winy=512
  243. ;
  244. ;       ; Render the mesh.
  245. ;       Set_Shading, Light=[-0.5, 0.5, 2.0], Reject=0
  246. ;       Tvscl, Polyshade(Vertex_List, Polygon_List, /Normal)
  247. ;
  248. ;
  249. ;       ; Create a cone (surface of revolution).
  250. ;       MESH_OBJ, 6, Vertex_List, Polygon_List, $
  251. ;          [[0.75, 0.0, 0.25], [0.5, 0.0, 0.75]], P1=16, P2=[0.5, 0.0, 0.0]
  252. ;
  253. ;       ; Create the window and view.
  254. ;       Window, 0, Xsize=512, Ysize=512
  255. ;       Create_View, Winx=512, Winy=512, Ax=30.0, Ay=(140.0), Zoom=0.5
  256. ;
  257. ;       ; Render the mesh.
  258. ;       Set_Shading, Light=[-0.5, 0.5, 2.0], Reject=0
  259. ;       Tvscl, Polyshade(Vertex_List, Polygon_List, /Data, /T3d)
  260. ;
  261. ; MODIFICATION HISTORY:
  262. ;       Written by:     Daniel Carr, Thu Mar 31 19:16:43 MST 1994
  263. ;-
  264.  
  265. PRO MESH_OBJ, obj_type, vertex_list, polygon_list, array1, array2, $
  266.               P1=p1, P2=p2, P3=p3, P4=p4, P5=p5, $
  267.               Degrees=degrees
  268.  
  269. CASE obj_type OF
  270.  
  271.    0: BEGIN ; Triangulated surface.
  272.       sz_array = Size(array1)
  273.       IF (sz_array[1] GE 3L) THEN vertex_list = array1 $
  274.       ELSE vertex_list = [array1, Replicate(0.0, 1, sz_array[2])]
  275.       
  276.       Triangulate, vertex_list[0, *], vertex_list[1, *], tri
  277.       polygon_list = [Replicate(3L, 1L, (N_Elements(tri) / 3L)), Temporary(tri)]
  278.       polygon_list = polygon_list[*]
  279.  
  280.       RETURN
  281.    END
  282.  
  283.    1: BEGIN ; Rectangular surface.
  284.       sz_array = Size(array1)
  285.       dim_x = sz_array[1]
  286.       dim_y = sz_array[2]
  287.       vert_num = dim_x * dim_y
  288.       indx_num = (dim_x - 1L) * (dim_y - 1L)
  289.       poly_num = 5L * indx_num
  290.  
  291.       vertex_list = Fltarr(3, vert_num, /Nozero)
  292.  
  293.       IF (N_Elements(p1) EQ dim_x) THEN $
  294.          vertex_list[0, *] = p1 # Replicate(1.0, dim_y) $
  295.       ELSE vertex_list[0, *] = Findgen(dim_x) # Replicate(1.0, dim_y)
  296.  
  297.       IF (N_Elements(p2) EQ dim_y) THEN $
  298.          vertex_list[1, *] = Replicate(1.0, dim_x) # p2 $
  299.       ELSE vertex_list[1, *] = Replicate(1.0, dim_x) # Findgen(dim_y)
  300.  
  301.       vertex_list[2, *] = Float(array1)
  302.  
  303.       polygon_list = Lonarr(poly_num, /Nozero)
  304.  
  305.       p_ind = 5L * Lindgen(indx_num)
  306.       y_inc = Replicate(1L, (dim_x - 1L)) # Lindgen(dim_y - 1L)
  307.  
  308.       polygon_list[p_ind] = 4L
  309.       p_ind = p_ind + 1L
  310.       polygon_list[p_ind] = Lindgen(indx_num) + y_inc[*]
  311.       y_inc = 0
  312.       polygon_list[p_ind + 1L] = polygon_list[p_ind] + 1L
  313.       p_ind = p_ind + 1L
  314.       polygon_list[p_ind + 1L] = polygon_list[p_ind] + dim_x
  315.       p_ind = p_ind + 1L
  316.       polygon_list[p_ind + 1L] = polygon_list[p_ind] - 1L
  317.       p_ind = 0
  318.  
  319.       RETURN
  320.    END
  321.  
  322.    2: BEGIN ; Polar surface.
  323.       sz_array = Size(array1)
  324.       dim_x = sz_array[1]
  325.       dim_y = sz_array[2]
  326.       vert_num = dim_x * dim_y
  327.  
  328.       vertex_list = Fltarr(3, vert_num, /Nozero)
  329.  
  330.       min_ang = 0.0
  331.       max_ang = 2.0 * !PI
  332.       min_rad = 0.0
  333.       max_rad = Float(dim_y - 1L)
  334.       IF (N_Elements(p1) GT 0L) THEN BEGIN
  335.          min_ang = Float(p1)
  336.          IF (Keyword_Set(degrees)) THEN min_ang = min_ang * !Dtor
  337.       ENDIF
  338.       IF (N_Elements(p2) GT 0L) THEN BEGIN
  339.          max_ang = Float(p2)
  340.          IF (Keyword_Set(degrees)) THEN max_ang = max_ang * !Dtor
  341.       ENDIF
  342.       IF (N_Elements(p3) GT 0L) THEN min_rad = Float(p3)
  343.       IF (N_Elements(p4) GT 0L) THEN max_rad = Float(p4)
  344.  
  345.       min_rad = min_rad > 1.0E-4
  346.       max_rad = max_rad > 1.0E-4
  347.       IF (min_ang EQ max_ang) THEN max_ang = max_ang + (2.0 * !PI)
  348.  
  349.       vertex_list[2, *] = Float(array1)
  350.       vertex_list[1, *] = Replicate(1.0, dim_x) # $
  351.          (min_rad + ((max_rad - min_rad) * Findgen(dim_y) / Float(dim_y - 1L)))
  352.       vertex_list[0, *] = $
  353.          (min_ang + ((max_ang - min_ang) * Findgen(dim_x) / $
  354.          Float(dim_x - 1L))) # Replicate(1.0, dim_y)
  355.  
  356.       indx_num = (dim_x - 1L) * (dim_y - 1L)
  357.       poly_num = 5L * indx_num
  358.  
  359.       polygon_list = Lonarr(poly_num, /Nozero)
  360.       y_inc = Replicate(1L, (dim_x - 1L)) # Lindgen(dim_y - 1L)
  361.  
  362.       p_ind = 5L * Lindgen(indx_num)
  363.  
  364.       polygon_list[p_ind] = 4L
  365.       polygon_list[p_ind + 1L] = Lindgen(indx_num) + y_inc[*]
  366.       y_inc = 0
  367.       polygon_list[p_ind + 2L] = polygon_list[p_ind + 1L] + dim_x
  368.       polygon_list[p_ind + 3L] = polygon_list[p_ind + 2L] + 1L
  369.       polygon_list[p_ind + 4L] = polygon_list[p_ind + 3L] - dim_x
  370.       p_ind = 0
  371.  
  372.       vertex_list = CV_COORD(From_Cylin=vertex_list, /To_Rect)
  373.       RETURN
  374.    END
  375.  
  376.    3: BEGIN ; Cylindrical surface.
  377.       sz_array = Size(array1)
  378.       dim_x = sz_array[1]
  379.       dim_y = sz_array[2]
  380.       vert_num = dim_x * dim_y
  381.  
  382.       vertex_list = Fltarr(3, vert_num, /Nozero)
  383.  
  384.       min_ang = 0.0
  385.       max_ang = 2.0 * !PI
  386.       min_len = 0.0
  387.       max_len = Float(dim_y - 1L)
  388.       IF (N_Elements(p1) GT 0L) THEN BEGIN
  389.          min_ang = Float(p1)
  390.          IF (Keyword_Set(degrees)) THEN min_ang = min_ang * !Dtor
  391.       ENDIF
  392.       IF (N_Elements(p2) GT 0L) THEN BEGIN
  393.          max_ang = Float(p2)
  394.          IF (Keyword_Set(degrees)) THEN max_ang = max_ang * !Dtor
  395.       ENDIF
  396.       IF (N_Elements(p3) GT 0L) THEN min_len = Float(p3)
  397.       IF (N_Elements(p4) GT 0L) THEN max_len = Float(p4)
  398.  
  399.       IF (min_ang EQ max_ang) THEN max_ang = max_ang + (2.0 * !PI)
  400.  
  401.       vertex_list[1, *] = Float(array1)
  402.       vertex_list[2, *] = Replicate(1.0, dim_x) # $
  403.          (min_len + ((max_len - min_len) * Findgen(dim_y) / Float(dim_y - 1L)))
  404.       vertex_list[0, *] = $
  405.          (min_ang + ((max_ang - min_ang) * Findgen(dim_x) / $
  406.          Float(dim_x - 1L))) # Replicate(1.0, dim_y)
  407.  
  408.       indx_num = (dim_x - 1L) * (dim_y - 1L)
  409.       poly_num = 5L * indx_num
  410.  
  411.       polygon_list = Lonarr(poly_num, /Nozero)
  412.       y_inc = Replicate(1L, (dim_x - 1L)) # Lindgen(dim_y - 1L)
  413.  
  414.       p_ind = 5L * Lindgen(indx_num)
  415.  
  416.       polygon_list[p_ind] = 4L
  417.       polygon_list[p_ind + 1L] = Lindgen(indx_num) + y_inc[*]
  418.       y_inc = 0
  419.       polygon_list[p_ind + 2L] = polygon_list[p_ind + 1L] + 1L
  420.       polygon_list[p_ind + 3L] = polygon_list[p_ind + 2L] + dim_x
  421.       polygon_list[p_ind + 4L] = polygon_list[p_ind + 3L] - 1L
  422.       p_ind = 0
  423.  
  424.       vertex_list = CV_COORD(From_Cylin=vertex_list, /To_Rect)
  425.       RETURN
  426.    END
  427.  
  428.    4: BEGIN ; Spherical surface.
  429.       sz_array = Size(array1)
  430.       dim_x = sz_array[1]
  431.       dim_y = sz_array[2]
  432.       vert_num = dim_x * dim_y
  433.  
  434.       vertex_list = Fltarr(3, vert_num, /Nozero)
  435.  
  436.       min_lon = 0.0
  437.       max_lon = 2.0 * !PI
  438.       min_lat = (-!PI) / 2.0
  439.       max_lat = (+!PI) / 2.0
  440.       IF (N_Elements(p1) GT 0L) THEN BEGIN
  441.          min_lon = Float(p1)
  442.          IF (Keyword_Set(degrees)) THEN min_lon = min_lon * !Dtor
  443.       ENDIF
  444.       IF (N_Elements(p2) GT 0L) THEN BEGIN
  445.          max_lon = Float(p2)
  446.          IF (Keyword_Set(degrees)) THEN max_lon = max_lon * !Dtor
  447.       ENDIF
  448.       IF (N_Elements(p3) GT 0L) THEN BEGIN
  449.          min_lat = Float(p3)
  450.          IF (Keyword_Set(degrees)) THEN min_lat = min_lat * !Dtor
  451.       ENDIF
  452.       IF (N_Elements(p4) GT 0L) THEN BEGIN
  453.          max_lat = Float(p4)
  454.          IF (Keyword_Set(degrees)) THEN max_lat = max_lat * !Dtor
  455.       ENDIF
  456.  
  457.       min_lat = (min_lat > (((-!PI) / 2.0) + 1.0E-4)) < $
  458.                            (((+!PI) / 2.0) - 1.0E-4)
  459.       max_lat = (max_lat > (((-!PI) / 2.0) + 1.0E-4)) < $
  460.                            (((+!PI) / 2.0) - 1.0E-4)
  461.       IF (min_lon EQ max_lon) THEN max_lon = max_lon + (2.0 * !PI)
  462.  
  463.       vertex_list[2, *] = Float(array1)
  464.       vertex_list[1, *] = Replicate(1.0, dim_x) # $
  465.          (min_lat + ((max_lat - min_lat) * Findgen(dim_y) / Float(dim_y - 1L)))
  466.       vertex_list[0, *] = $
  467.          (min_lon + ((max_lon - min_lon) * Findgen(dim_x) / $
  468.          Float(dim_x - 1L))) # Replicate(1.0, dim_y)
  469.  
  470.       indx_num = (dim_x - 1L) * (dim_y - 1L)
  471.       poly_num = 5L * indx_num
  472.  
  473.       polygon_list = Lonarr(poly_num, /Nozero)
  474.       y_inc = Replicate(1L, (dim_x - 1L)) # Lindgen(dim_y - 1L)
  475.  
  476.       p_ind = 5L * Lindgen(indx_num)
  477.  
  478.       polygon_list[p_ind] = 4L
  479.       polygon_list[p_ind + 1L] = Lindgen(indx_num) + y_inc[*]
  480.       y_inc = 0
  481.       polygon_list[p_ind + 2L] = polygon_list[p_ind + 1L] + 1L
  482.       polygon_list[p_ind + 3L] = polygon_list[p_ind + 2L] + dim_x
  483.       polygon_list[p_ind + 4L] = polygon_list[p_ind + 3L] - 1L
  484.       p_ind = 0
  485.  
  486.       vertex_list = CV_COORD(From_Sphere=vertex_list, /To_Rect)
  487.       RETURN
  488.    END
  489.  
  490.    5: BEGIN ; Surface of extrusion.
  491.       sz_array = Size(array1)
  492.       max_ind = sz_array[2] - 1L
  493.       steps = 1L
  494.       IF (N_Elements(p1) GT 0L) THEN steps = Long(p1) > 1L
  495.  
  496.       vert_num = sz_array[2] * (steps + 1L)
  497.  
  498.       indx_num = max_ind * steps
  499.       poly_num = 5L * indx_num
  500.  
  501.       polygon_list = Lonarr(poly_num, /Nozero)
  502.       y_inc = Replicate(1L, max_ind) # Lindgen(steps)
  503.  
  504.       p_ind = 5L * Lindgen(indx_num)
  505.  
  506.       polygon_list[p_ind] = 4L
  507.       polygon_list[p_ind + 1L] = Lindgen(indx_num) + y_inc[*]
  508.       y_inc = 0
  509.       polygon_list[p_ind + 2L] = polygon_list[p_ind + 1L] + 1L
  510.       polygon_list[p_ind + 3L] = polygon_list[p_ind + 2L] + sz_array[2]
  511.       polygon_list[p_ind + 4L] = polygon_list[p_ind + 3L] - 1L
  512.       p_ind = 0
  513.  
  514.       ex_vec = [0.0, 0.0, 1.0]
  515.       IF (N_Elements(p2) GT 0L) THEN ex_vec = Float(p2)
  516.       len = Sqrt(ex_vec[0]^2 + ex_vec[1]^2 + ex_vec[2]^2)
  517.       IF (len EQ 0.0) THEN BEGIN
  518.          ex_vec = [0.0, 0.0, 1.0]
  519.          len = 1.0
  520.       ENDIF
  521.       len = Sqrt(ex_vec[0]^2 + ex_vec[1]^2 + ex_vec[2]^2)
  522.       ex_vec = ex_vec / len
  523.  
  524.       z_ang = 0.0
  525.       y_len = Sqrt(ex_vec[0]^2 + ex_vec[1]^2)
  526.       IF (y_len GT 0.0) THEN $
  527.          z_ang = Atan(ex_vec[1], ex_vec[0]) * !Radeg
  528.       y_ang = 0.0
  529.       IF ((ex_vec[2] NE 0.0) OR (y_len GT 0.0)) THEN $
  530.          y_ang = Atan(ex_vec[2], y_len) * !Radeg
  531.  
  532.       save_pt = !P.T
  533.       T3d, /Reset
  534.       T3d, Rotate=[0.0, 0.0, (-z_ang)]
  535.       T3d, Rotate=[0.0, (y_ang), 0.0]
  536.       T3d, Rotate=[0.0, (-90.0), 0.0]
  537.  
  538.       IF (sz_array[1] EQ 2L) THEN $
  539.          perim = Vert_T3d([array1[0, *], array1[1, *], $
  540.                           Replicate(0.0, 1L, sz_array[2])]) $
  541.       ELSE perim = Vert_T3d(array1)
  542.  
  543.       vertex_list = Fltarr(3, vert_num, /Nozero)
  544.       vertex_list[0, *] = Reform(perim[0, *]) # Replicate(1.0, (steps + 1L))
  545.       vertex_list[1, *] = Reform(perim[1, *]) # Replicate(1.0, (steps + 1L))
  546.       vertex_list[2, *] = $
  547.          (Reform(perim[2, *]) # Replicate(1.0, (steps + 1L))) + $
  548.          Replicate(1.0, sz_array[2]) # $
  549.          (len * Findgen(steps + 1L) / Float(steps))
  550.  
  551.       T3d, /Reset
  552.       T3d, Rotate=[0.0, (90.0), 0.0]
  553.       T3d, Rotate=[0.0, (-y_ang), 0.0]
  554.       T3d, Rotate=[0.0, 0.0, (z_ang)]
  555.  
  556.       vertex_list = Vert_T3d(vertex_list, /No_Copy)
  557.       !P.T = save_pt
  558.  
  559.       RETURN
  560.    END
  561.  
  562.    6: BEGIN ; Surface of revolution.
  563.       sz_array = Size(array1)
  564.       max_ind = sz_array[2] - 1L
  565.       steps = 3L
  566.       IF (N_Elements(p1) GT 0L) THEN steps = p1 > 3L
  567.  
  568.       vert_num = sz_array[2] * (steps + 1L)
  569.  
  570.       indx_num = max_ind * steps
  571.       poly_num = 5L * indx_num
  572.  
  573.       polygon_list = Lonarr(poly_num, /Nozero)
  574.       y_inc = Replicate(1L, max_ind) # Lindgen(steps)
  575.  
  576.       p_ind = 5L * Lindgen(indx_num)
  577.  
  578.       polygon_list[p_ind] = 4L
  579.       polygon_list[p_ind + 1L] = Lindgen(indx_num) + y_inc[*]
  580.       y_inc = 0
  581.       polygon_list[p_ind + 2L] = polygon_list[p_ind + 1L] + sz_array[2]
  582.       polygon_list[p_ind + 3L] = polygon_list[p_ind + 2L] + 1L
  583.       polygon_list[p_ind + 4L] = polygon_list[p_ind + 3L] - sz_array[2]
  584.       p_ind = 0
  585.  
  586.       min_ang = 0.0
  587.       max_ang = 2.0 * !PI
  588.       IF (N_Elements(p4) GT 0L) THEN BEGIN
  589.          min_ang = Float(p4)
  590.          IF (Keyword_Set(degrees)) THEN min_ang = min_ang * !Dtor
  591.       ENDIF
  592.       IF (N_Elements(p5) GT 0L) THEN BEGIN
  593.          max_ang = Float(p5)
  594.          IF (Keyword_Set(degrees)) THEN max_ang = max_ang * !Dtor
  595.       ENDIF
  596.  
  597.       IF (min_ang EQ max_ang) THEN max_ang = max_ang + (2.0 * !PI)
  598.  
  599.       rot_point = [0.0, 0.0, 0.0]
  600.       IF (N_Elements(p2) GT 0L) THEN rot_point = Float(p2)
  601.       rot_vec = [0.0, 0.0, 1.0]
  602.       IF (N_Elements(p3) GT 0L) THEN rot_vec = Float(p3)
  603.       len = Sqrt(rot_vec[0]^2 + rot_vec[1]^2 + rot_vec[2]^2)
  604.       IF (len EQ 0.0) THEN BEGIN
  605.          rot_vec = [0.0, 0.0, 1.0]
  606.          len = 1.0
  607.       ENDIF
  608.       len = Sqrt(rot_vec[0]^2 + rot_vec[1]^2 + rot_vec[2]^2)
  609.       rot_vec = rot_vec / len
  610.  
  611.       z_ang = 0.0
  612.       y_len = Sqrt(rot_vec[0]^2 + rot_vec[1]^2)
  613.       IF (y_len GT 0.0) THEN $
  614.          z_ang = Atan(rot_vec[1], rot_vec[0]) * !Radeg
  615.       y_ang = 0.0
  616.       IF ((rot_vec[2] NE 0.0) OR (y_len GT 0.0)) THEN $
  617.          y_ang = Atan(rot_vec[2], y_len) * !Radeg
  618.  
  619.       save_pt = !P.T
  620.       T3d, /Reset
  621.       T3d, Translate=[(-rot_point[0]), (-rot_point[1]), (-rot_point[2])]
  622.       T3d, Rotate=[0.0, 0.0, (-z_ang)]
  623.       T3d, Rotate=[0.0, (y_ang - 90.0), 0.0]
  624.  
  625.       IF (sz_array[1] EQ 2L) THEN $
  626.          sweep = Vert_T3d([array1[0, *], array1[1, *], $
  627.                           Replicate(0.0, 1L, sz_array[2])]) $
  628.       ELSE sweep = Vert_T3d(array1)
  629.  
  630.       neg_ind = Where(sweep[0, *] LT 0.0)
  631.       sweep[0, *] = Abs(sweep[0, *]) > 1.0E-4
  632.       IF (neg_ind[0] GE 0L) THEN sweep[0, neg_ind] = sweep[0, neg_ind] * (-1.0)
  633.       neg_ind = 0
  634.  
  635.       vertex_list = Fltarr(3, vert_num, /Nozero)
  636.       vertex_list[0, *] = Reform(sweep[0, *]) # Replicate(1.0, (steps + 1L))
  637.       vertex_list[1, *] = Reform(sweep[1, *]) # Replicate(1.0, (steps + 1L))
  638.       vertex_list[2, *] = Reform(sweep[2, *]) # Replicate(1.0, (steps + 1L))
  639.  
  640.       perim_ind = Lindgen(sz_array[2])
  641.  
  642.       FOR i=0L, steps DO BEGIN
  643.          T3d, /Reset
  644.          T3d, Rotate=[0.0, 0.0, (!Radeg * $
  645.             ((Float(i) * (max_ang - min_ang) / Float(steps)) + min_ang))]
  646.          vertex_list[*, perim_ind] = Vert_T3d(vertex_list[*, perim_ind])
  647.  
  648.          perim_ind = perim_ind + sz_array[2]
  649.       ENDFOR
  650.       perim_ind = 0
  651.  
  652.       T3d, /Reset
  653.       T3d, Rotate=[0.0, (90.0 - y_ang), 0.0]
  654.       T3d, Rotate=[0.0, 0.0, (z_ang)]
  655.       T3d, Translate=[rot_point[0], rot_point[1], rot_point[2]]
  656.  
  657.       vertex_list = Vert_T3d(vertex_list, /No_Copy)
  658.       !P.T = save_pt
  659.  
  660.       RETURN
  661.    END
  662.  
  663.    7: BEGIN ; Ruled surface.
  664.       sz_array = Size(array1)
  665.       sz_array2 = Size(array2)
  666.       IF (sz_array[1] EQ 2L) THEN $
  667.          start_rule = [array1[0, *], array1[1, *], $
  668.                        Replicate(0.0, 1L, sz_array[2])] $
  669.       ELSE start_rule = array1
  670.       IF (sz_array2[1] EQ 2L) THEN $
  671.          end_rule = [array2[0, *], array2[1, *], $
  672.                      Replicate(0.0, 1L, sz_array2[2])] $
  673.       ELSE end_rule = array2
  674.  
  675.       IF (sz_array[2] GT sz_array2[2]) THEN $
  676.          end_rule = Congrid(end_rule, 3, sz_array[2], /Interp, /Minus_One)
  677.  
  678.       IF (sz_array[2] LT sz_array2[2]) THEN BEGIN
  679.          start_rule = Congrid(start_rule, 3, sz_array2[2], /Interp, /Minus_One)
  680.          sz_array = Size(start_rule)
  681.       ENDIF
  682.  
  683.       steps = 1L
  684.       IF (N_Elements(p1) GT 0L) THEN steps = Long(p1) > 1L
  685.  
  686.       dim_x = sz_array[2]
  687.       dim_y = steps + 1L
  688.  
  689.       vert_num = dim_x * dim_y
  690.       indx_num = (dim_x - 1L) * (dim_y - 1L)
  691.       poly_num = 5L * indx_num
  692.  
  693.       vertex_list = Fltarr(3, vert_num, /Nozero)
  694.  
  695.       strip_ind = Lindgen(dim_x)
  696.       FOR i=0L, steps DO BEGIN
  697.          fac = Float(i) / Float(steps)
  698.          vertex_list[0, strip_ind] = $
  699.             ((1.0 - fac) * start_rule[0, *]) + (fac * end_rule[0, *])
  700.          vertex_list[1, strip_ind] = $
  701.             ((1.0 - fac) * start_rule[1, *]) + (fac * end_rule[1, *])
  702.          vertex_list[2, strip_ind] = $
  703.             ((1.0 - fac) * start_rule[2, *]) + (fac * end_rule[2, *])
  704.  
  705.          strip_ind = strip_ind + dim_x
  706.       ENDFOR
  707.  
  708.       polygon_list = Lonarr(poly_num, /Nozero)
  709.  
  710.       p_ind = 5L * Lindgen(indx_num)
  711.       y_inc = Replicate(1L, (dim_x - 1L)) # Lindgen(dim_y - 1L)
  712.  
  713.       polygon_list[p_ind] = 4L
  714.       p_ind = p_ind + 1L
  715.       polygon_list[p_ind] = Lindgen(indx_num) + y_inc[*]
  716.       y_inc = 0
  717.       polygon_list[p_ind + 1L] = polygon_list[p_ind] + dim_x
  718.       p_ind = p_ind + 1L
  719.       polygon_list[p_ind + 1L] = polygon_list[p_ind] + 1L
  720.       p_ind = p_ind + 1L
  721.       polygon_list[p_ind + 1L] = polygon_list[p_ind] - dim_x
  722.       p_ind = 0
  723.  
  724.       RETURN
  725.    END
  726.  
  727.    ELSE:
  728. ENDCASE
  729.  
  730. RETURN
  731. END
  732.